<template>
  <div>
    <div class="search-container">
      <el-input v-model="search.username" placeholder="用户名" style="width: 200px; margin-right: 10px" />
      <el-input v-model="search.nickname" placeholder="昵称" style="width: 200px; margin-right: 10px" />
      <el-select v-model="search.role" placeholder="角色" clearable style="width: 200px; margin-right: 10px">
        <el-option label="管理员" value="ADMIN" />
        <el-option label="普通用户" value="USER" />
      </el-select>
      <el-button @click="searchMethod">搜索</el-button>
      <el-button @click="resetSearch">重置</el-button>
    </div>

    <el-table :data="tableData" border style="margin-top: 20px">
      <el-table-column prop="id" label="ID" width="60"></el-table-column>
      <el-table-column prop="nickname" label="昵称"></el-table-column>
      <el-table-column prop="username" label="用户名"></el-table-column>
      <el-table-column prop="sex" label="性别" width="80">
        <template #default="{ row }">
          {{ row.sex === '男' ? '男' : '女' }}
        </template>
      </el-table-column>
      <el-table-column prop="age" label="年龄" width="80"></el-table-column>
      <el-table-column prop="phone" label="电话"></el-table-column>
      <el-table-column prop="email" label="邮箱"></el-table-column>
      <el-table-column prop="role" label="角色">
        <template #default="{ row }">
          <el-tag :type="row.role === 'ADMIN' ? 'danger' : 'success'">
            {{ row.role === 'ADMIN' ? '管理员' : '普通用户' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
      <el-table-column prop="updateTime" label="更新时间" width="180"></el-table-column>
      <el-table-column label="操作" width="200" fixed="right">
        <template #default="{ row }">
          <el-button @click="openDialog(row)" size="small" type="primary">编辑</el-button>
          <el-popconfirm
            title="确定要删除该用户吗？"
            confirm-button-text="确定"
            cancel-button-text="取消"
            @confirm="handleDelete(row)">
            <template #reference>
              <el-button type="danger" size="small">删除</el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>

    <el-pagination
      layout="sizes, prev, pager, next, jumper, total"
      @size-change="findSize"
      @current-change="findPage"
      :page-size="pageSize"
      :current-page="currentPage"
      :total="total"
      :page-sizes="[5, 10, 20, 30, 50]"
      style="text-align: center; padding: 20px 0" />

    <el-button @click="toggleAddUserForm" type="success" style="margin-top: 20px">添加用户</el-button>

    <!-- 添加用户表单 -->
    <div v-show="showAddForm" class="transition-box" style="margin-top: 20px;">
      <el-form :model="form" :rules="rules" ref="formRef" label-width="80px">
        <el-form-item label="头像" prop="avatar">
          <el-upload
            :action="uploadPath"
            :before-upload="beforeUpload"
            :show-file-list="false"
            :on-success="handleAvatarSuccessAdd"
            :on-error="handleAvatarErrorAdd"
            :headers="{ Authorization: getStorage('TOKEN') }"
            ref="upload"
          >
            <el-avatar
              :src="form.avatar || noAvatar"
              @click="handleAvatarClick"
            />
            <el-input v-model="form.avatar" type="hidden"></el-input>
          </el-upload>
        </el-form-item>
        <el-form-item label="昵称" prop="nickname">
          <el-input v-model="form.nickname" placeholder="请输入昵称" />
        </el-form-item>
        <el-form-item label="用户名" prop="username">
          <el-input v-model="form.username" placeholder="请输入用户名" />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="form.password" placeholder="请输入密码" type="password" />
        </el-form-item>
        <el-form-item label="性别" prop="sex">
          <el-radio-group v-model="form.sex">
            <el-radio label="男">男</el-radio>
            <el-radio label="女">女</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="年龄" prop="age">
          <el-input-number v-model="form.age" :min="1" :max="120" />
        </el-form-item>
        <el-form-item label="电话" prop="phone">
          <el-input v-model="form.phone" placeholder="请输入电话号码" />
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="form.email" placeholder="请输入邮箱" />
        </el-form-item>
        <el-form-item label="角色" prop="role">
          <el-select v-model="form.role" placeholder="请选择角色">
            <el-option label="管理员" value="ADMIN" />
            <el-option label="普通用户" value="USER" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">保存</el-button>
          <el-button @click="resetForm">重置</el-button>
        </el-form-item>
      </el-form>
    </div>

    <!-- 编辑用户对话框 -->
    <el-dialog title="编辑用户信息" v-model="dialogVisible" width="500px" :append-to-body="true">
      <el-form :model="dialogForm" :rules="rules" ref="dialogFormRef" label-width="80px">
        <el-form-item label="头像" prop="avatar">
          <el-upload
            :action="uploadPath"
            :before-upload="beforeUpload"
            :show-file-list="false"
            :on-success="handleAvatarSuccessAdd"
            :on-error="handleAvatarErrorAdd"
            :headers="{ Authorization: getStorage('TOKEN') }"
            ref="upload"
          >
            <el-avatar
              :src="dialogForm.avatar || noAvatar"
              @click="handleAvatarClick"
            />
            <el-input v-model="dialogForm.avatar" type="hidden"></el-input>
          </el-upload>
        </el-form-item>
        <el-form-item label="昵称" prop="nickname">
          <el-input v-model="dialogForm.nickname" placeholder="请输入昵称" />
        </el-form-item>
        <el-form-item label="用户名" prop="username">
          <el-input v-model="dialogForm.username" placeholder="请输入用户名" />
        </el-form-item>
        <el-form-item label="性别" prop="sex">
          <el-radio-group v-model="dialogForm.sex">
            <el-radio label="男">男</el-radio>
            <el-radio label="女">女</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="年龄" prop="age">
          <el-input-number v-model="dialogForm.age" :min="1" :max="120" />
        </el-form-item>
        <el-form-item label="电话" prop="phone">
          <el-input v-model="dialogForm.phone" placeholder="请输入电话号码" />
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="dialogForm.email" placeholder="请输入邮箱" />
        </el-form-item>
        <el-form-item label="角色" prop="role">
          <el-select v-model="dialogForm.role" placeholder="请选择角色">
            <el-option label="管理员" value="ADMIN" />
            <el-option label="普通用户" value="USER" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleEdit">保存</el-button>
          <el-button @click="dialogVisible = false">取消</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { getUserList as pageUser,
  add as addUser,
  update as updateUser,
  del as deleteUser,
} from '@/api/User.js'
import { getStorage } from '@/utils/storage.js'
import noAvatar from '@/assets/no-avatar.png'

// 数据
const tableData = ref([])
const total = ref(0)
const pageSize = ref(10)
const currentPage = ref(1)

const BASE_URL = import.meta.env.VITE_BASE_API
const uploadPath = BASE_URL + '/common/upload'

// 表单
const dialogForm = reactive({
  id: '',
  nickname: '',
  username: '',
  sex: '男',
  age: 18,
  avatar: '',
  phone: '',
  email: '',
  role: 'USER'
})

const form = reactive({
  nickname: '',
  username: '',
  password: '',
  sex: '男',
  age: 18,
  avatar: '',
  phone: '',
  email: '',
  role: 'USER'
})

// 表单验证规则
const rules = {
  avatar: [{ required: true, message: '请上传头像', trigger: 'blur' }],
  nickname: [{ required: true, message: '请输入昵称', trigger: 'blur' }],
  username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    { min: 6, max: 20, message: '密码长度在 6 到 20 个字符', trigger: 'blur' }
  ],
  sex: [{ required: true, message: '请选择性别', trigger: 'blur' }],
  age: [{ required: true, message: '请输入年龄', trigger: 'blur' }],
  phone: [{ required: true, message: '请输入手机号', trigger: 'blur' },
    { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }],
  email: [{ required: true, message: '请输入邮箱', trigger: 'blur' }],
  role: [{ required: true, message: '请选择角色', trigger: 'change' }]
}

const dialogVisible = ref(false)
const showAddForm = ref(false)
const dialogFormRef = ref(null)
const formRef = ref(null)

// 分页方法
const findSize = (size) => {
  pageSize.value = size
  fetch()
}

const findPage = (page) => {
  currentPage.value = page
  fetch()
}

// 获取用户列表
const fetch = async (page = currentPage.value, size = pageSize.value, params = {}) => {
  try {
    const { data } = await pageUser({
      pageNum: page,
      pageSize: size,
      ...params
    })
    tableData.value = data.records
    total.value = data.total
  } catch (error) {
    console.error('获取用户列表失败:', error)
    ElMessage.error('获取用户列表失败')
  }
}

// 打开编辑对话框
const openDialog = (row) => {
  dialogVisible.value = true
  Object.keys(dialogForm).forEach(key => {
    if (row[key] !== undefined) {
      dialogForm[key] = row[key]
    }
  })
}

// 编辑用户
const handleEdit = async () => {
  dialogFormRef.value.validate().then(() => {
    updateUser(dialogForm).then((res) => {
      if (res.code === 1) {
        ElMessage.success({
          message: res.msg || '更新成功',
          type: 'success'
        })
        fetch()
        dialogVisible.value = false
      } else {
        ElMessage.error({
          message: res.msg || '更新失败',
          type: 'error'
        })
      }
    }).catch(err => {
      console.error('更新用户失败:', err)
      ElMessage.error('更新用户失败')
    })
  })
}

// 删除用户
const handleDelete = async (row) => {
  deleteUser(row.id).then((res) => {
    if (res.code === 1) {
      ElMessage.success({
        message: res.msg || '删除成功',
        type: 'success'
      })
      fetch()
    } else {
      ElMessage.error({
        message: res.msg || '删除失败',
        type: 'error'
      })
    }
  }).catch(err => {
    console.error('删除用户失败:', err)
    ElMessage.error('删除用户失败')
  })
}

// 切换添加用户表单显示状态
const toggleAddUserForm = () => {
  showAddForm.value = !showAddForm.value
}

// 添加用户
const onSubmit = async () => {
  formRef.value.validate().then(() => {
    addUser(form).then((res) => {
      if (res.code === 1) {
        ElMessage.success({
          message: res.msg || '添加成功',
          type: 'success'
        })
        fetch()
        resetForm()
      } else {
        ElMessage.error({
          message: res.msg || '添加失败',
          type: 'error'
        })
      }
    }).catch(err => {
      console.error('添加用户失败:', err)
      ElMessage.error('添加用户失败')
    })
  })
}

// 重置表单
const resetForm = () => {
  Object.keys(form).forEach(key => {
    if (key === 'sex') {
      form[key] = '男'
    } else if (key === 'age') {
      form[key] = 18
    } else if (key === 'role') {
      form[key] = 'USER'
    } else {
      form[key] = ''
    }
  })
  if (formRef.value) {
    formRef.value.resetFields()
  }
}

// 搜索相关
const search = reactive({
  username: '',
  nickname: '',
  role: ''
})

const searchMethod = () => {
  const params = {}
  if (search.username) params.username = search.username
  if (search.nickname) params.nickname = search.nickname
  if (search.role) params.role = search.role

  fetch(1, pageSize.value, params)
  currentPage.value = 1
}

const resetSearch = () => {
  search.username = ''
  search.nickname = ''
  search.role = ''
  fetch()
}

const handleAvatarClick = () => {
  proxy.$refs.upload.uploadFiles()
}

// 上传文件前的校验
const beforeUpload = (file) => {
  const isImage = file.type.startsWith('image/')
  const isLt2M = file.size / 1024 / 1024 < 2
  if (!isImage) {
    ElMessage.error('上传文件只能是图片!')
  }
  if (!isLt2M) {
    ElMessage.error('上传图片大小不能超过 2MB!')
  }
  return isImage && isLt2M
}

// 上传图片成功后的回调
const handleAvatarSuccessAdd = (res, file) => {
  if (dialogVisible.value) {
    dialogForm.avatar = file.response.data
  } else {
    form.avatar = file.response.data
  }
}

// 上传图片失败后的回调
const handleAvatarErrorAdd = (err, file) => {
  if (err.toString().indexOf('401')) {
    ElMessage.error('请先登录!')
    router.push('/login')
  } else {
    ElMessage.error(err)
  }
}

// 页面加载时获取数据
onMounted(async () => {
  await fetch()
})
</script>

<style scoped lang="scss">
.search-container {
  display: flex;
  margin-bottom: 20px;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

h1 {
  margin-bottom: 20px;
  color: #303133;
}

.transition-box {
  transition: all 0.3s ease;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 20px;
  background-color: #f9f9f9;
  margin-bottom: 20px;
}

.el-form {
  max-width: 600px;
}

.el-pagination {
  margin: 20px 0;
}

.el-table {
  margin-bottom: 20px;
}

.el-tag {
  font-weight: bold;
}

.el-button + .el-button {
  margin-left: 10px;
}

.el-form-item__content {
  display: flex;
  align-items: center;
}

.el-input-number {
  width: 180px;
}
</style>
